$(INSTALL_DATA) libxenctrl.a $(DESTDIR)$(LIBDIR)
ln -sf libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenctrl.so.$(MAJOR)
ln -sf libxenctrl.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxenctrl.so
- $(INSTALL_DATA) xenctrl.h xentoollog.h $(DESTDIR)$(INCLUDEDIR)
+ $(INSTALL_DATA) xenctrl.h xenctrlosdep.h xentoollog.h $(DESTDIR)$(INCLUDEDIR)
$(INSTALL_PROG) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
$(INSTALL_DATA) libxenguest.a $(DESTDIR)$(LIBDIR)
ln -sf libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenguest.so.$(MAJOR)
#include <unistd.h>
#include <fcntl.h>
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle linux_privcmd_open(xc_interface *xch)
{
int flags, saved_errno;
int fd = open("/proc/xen/privcmd", O_RDWR);
if ( fd == -1 )
{
PERROR("Could not obtain handle on privileged command interface");
- return -1;
+ return XC_OSDEP_OPEN_ERROR;
}
/* Although we return the file handle as the 'xc handle' the API
goto error;
}
- return fd;
+ xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+
+ return (xc_osdep_handle)fd;
error:
saved_errno = errno;
close(fd);
errno = saved_errno;
-
- return -1;
+ return XC_OSDEP_OPEN_ERROR;
}
-int xc_interface_close_core(xc_interface *xch)
+static int linux_privcmd_close(xc_interface *xch, xc_osdep_handle h)
{
- return close(xch->fd);
+ int fd = (int)h;
+ return close(fd);
}
static int xc_map_foreign_batch_single(xc_interface *xch, uint32_t dom,
(unsigned long)hypercall);
}
+static struct xc_osdep_ops linux_privcmd_ops = {
+ .open = &linux_privcmd_open,
+ .close = &linux_privcmd_close,
+};
+
#define DEVXEN "/dev/xen/"
-int xc_evtchn_open_core(xc_evtchn *xce)
+static xc_osdep_handle linux_evtchn_open(xc_evtchn *xce)
{
- return open(DEVXEN "evtchn", O_RDWR);
+ int fd = open(DEVXEN "evtchn", O_RDWR);
+ if ( fd == -1 )
+ return XC_OSDEP_OPEN_ERROR;
+
+ xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
}
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int linux_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
{
- return close(xce->fd);
+ int fd = (int)h;
+ return close(fd);
}
int xc_evtchn_fd(xc_evtchn *xce)
return write_exact(xce->fd, (char *)&port, sizeof(port));
}
+static struct xc_osdep_ops linux_evtchn_ops = {
+ .open = &linux_evtchn_open,
+ .close = &linux_evtchn_close,
+};
+
/* Optionally flush file to disk and discard page cache */
void discard_file_cache(xc_interface *xch, int fd, int flush)
{
errno = saved_errno;
}
-int xc_gnttab_open_core(xc_gnttab *xcg)
+static xc_osdep_handle linux_gnttab_open(xc_gnttab *xcg)
{
- return open(DEVXEN "gntdev", O_RDWR);
+ int fd = open(DEVXEN "gntdev", O_RDWR);
+
+ if ( fd == -1 )
+ return XC_OSDEP_OPEN_ERROR;
+
+ xcg->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
}
-int xc_gnttab_close_core(xc_gnttab *xcg)
+static int linux_gnttab_close(xc_gnttab *xcg, xc_osdep_handle h)
{
- return close(xcg->fd);
+ int fd = (int)h;
+ return close(fd);
}
void *xc_gnttab_map_grant_ref(xc_gnttab *xch, uint32_t domid, uint32_t ref, int prot)
return 0;
}
+static struct xc_osdep_ops linux_gnttab_ops = {
+ .open = &linux_gnttab_open,
+ .close = &linux_gnttab_close,
+};
+
+static struct xc_osdep_ops *linux_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+ switch ( type )
+ {
+ case XC_OSDEP_PRIVCMD:
+ return &linux_privcmd_ops;
+ case XC_OSDEP_EVTCHN:
+ return &linux_evtchn_ops;
+ case XC_OSDEP_GNTTAB:
+ return &linux_gnttab_ops;
+ default:
+ return NULL;
+ }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+ .name = "Linux Native OS interface",
+ .init = &linux_osdep_init,
+};
+
/*
* Local variables:
* mode: C
extern struct wait_queue_head event_queue;
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle minios_privcmd_open(xc_interface *xch)
{
- return alloc_fd(FTYPE_XC);
+ int fd = alloc_fd(FTYPE_XC);
+
+ if ( fd == -1)
+ return XC_OSDEP_OPEN_ERROR;
+
+ xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
}
-int xc_interface_close_core(xc_interface *xch)
+static int minios_privcmd_close(xc_interface *xch, xc_osdep_handle h)
{
- return close(xch->fd);
+ int fd = (int)h;
+ return close(fd);
}
void minios_interface_close_fd(int fd)
return call.result;
}
-int xc_evtchn_open_core(xc_evtchn *xce)
+static struct xc_osdep_ops minios_privcmd_ops = {
+ .open = &minios_privcmd_open,
+ .close = &minios_privcmd_close,
+};
+
+static xc_osdep_handle minios_evtchn_open(xc_evtchn *xce)
{
int fd = alloc_fd(FTYPE_EVTCHN), i;
+ if ( fd == -1 )
+ return XC_OSDEP_OPEN_ERROR;
for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
files[fd].evtchn.ports[i].port = -1;
files[fd].evtchn.ports[i].bound = 0;
}
printf("evtchn_open() -> %d\n", fd);
- return fd;
+ xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
}
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int minios_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
{
- return close(xce->fd);
+ int fd = (int)h;
+ return close(fd);
}
void minios_evtchn_close_fd(int fd)
return 0;
}
+static struct xc_osdep_ops minios_evtchn_ops = {
+ .open = &minios_evtchn_open,
+ .close = &minios_evtchn_close,
+};
+
/* Optionally flush file to disk and discard page cache */
void discard_file_cache(xc_interface *xch, int fd, int flush)
{
fsync(fd);
}
-int xc_gnttab_open_core(xc_gnttab *xcg)
+static xc_osdep_handle minios_gnttab_open(xc_gnttab *xcg)
{
- int fd;
- fd = alloc_fd(FTYPE_GNTMAP);
+ int fd = alloc_fd(FTYPE_GNTMAP);
+ if ( fd == -1 )
+ return XC_OSDEP_OPEN_ERROR;
gntmap_init(&files[fd].gntmap);
- return fd;
+ xcg->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
}
-int xc_gnttab_close_core(xc_gnttab *xcg)
+static int minios_gnttab_close(xc_gnttab *xcg, xc_osdep_handle h)
{
- return close(xcg->fd);
+ int fd = (int)h;
+ return close(fd);
}
void minios_gnttab_close_fd(int fd)
return ret;
}
+static struct xc_osdep_ops minios_gnttab_ops = {
+ .open = &minios_gnttab_open,
+ .close = &minios_gnttab_close,
+};
+
+static struct xc_osdep_ops *minios_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+ switch ( type )
+ {
+ case XC_OSDEP_PRIVCMD:
+ return &minios_privcmd_ops;
+ case XC_OSDEP_EVTCHN:
+ return &minios_evtchn_ops;
+ case XC_OSDEP_GNTTAB:
+ return &minios_gnttab_ops;
+ default:
+ return NULL;
+ }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+ .name = "Minios Native OS interface",
+ .init = &minios_osdep_init,
+};
+
/*
* Local variables:
* mode: C
#include <unistd.h>
#include <fcntl.h>
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle netbsd_privcmd_open(xc_interface *xch)
{
int flags, saved_errno;
int fd = open("/kern/xen/privcmd", O_RDWR);
if ( fd == -1 )
{
PERROR("Could not obtain handle on privileged command interface");
- return -1;
+ return XC_OSDEP_OPEN_ERROR;
}
/* Although we return the file handle as the 'xc handle' the API
goto error;
}
- return fd;
+ xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+
+ return (xc_osinteface_handle)fd;
error:
saved_errno = errno;
close(fd);
errno = saved_errno;
- return -1;
+ return XC_OSDEP_OPEN_ERROR;
}
-int xc_interface_close_core(xc_interface *xch)
+static int netbsd_privcmd_close(xc_interface *xch, xc_osdep_handle h)
{
- return close(xch->fd);
+ int fd = (int)h;
+ return close(fd);
}
void *xc_map_foreign_batch(xc_interface *xch, uint32_t dom, int prot,
return (hypercall->retval);
}
+static struct xc_osdep_ops netbsd_privcmd_ops = {
+ .open = &netbsd_privcmd_open,
+ .close = &netbsd_privcmd_close,
+};
+
#define EVTCHN_DEV_NAME "/dev/xenevt"
-int xc_evtchn_open_core(xc_evtchn *xce)
+static xc_osdep_handle netbsd_evtchn_open(xc_evtchn *xce)
{
- return open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
+ int fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
+ if ( fd == -1 )
+ return XC_OSDEP_OPEN_ERROR;
+
+ xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
}
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int netbsd_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
{
- return close(xce->fd);
+ int fd = (int)h;
+ return close(fd);
}
int xc_evtchn_fd(xc_evtchn *xce)
return write_exact(xce->fd, (char *)&port, sizeof(port));
}
+static struct xc_osdep_ops netbsd_evtchn_ops = {
+ .open = &netbsd_evtchn_open,
+ .close = &netbsd_evtchn_close,
+};
+
/* Optionally flush file to disk and discard page cache */
void discard_file_cache(xc_interface *xch, int fd, int flush)
{
errno = saved_errno;
}
+static struct xc_osdep_ops *netbsd_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+ switch ( type )
+ {
+ case XC_OSDEP_PRIVCMD:
+ return &netbsd_privcmd_ops;
+ case XC_OSDEP_EVTCHN:
+ return &netbsd_evtchn_ops;
+ case XC_OSDEP_GNTTAB:
+ ERROR("GNTTAB interface not supported on this platform");
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+ .name = "Netbsd Native OS interface",
+ .init = &netbsd_osdep_init,
+};
+
/*
* Local variables:
* mode: C
#include <pthread.h>
#include <assert.h>
+/*
+ * Returns a (shallow) copy of the xc_osdep_info_t for the
+ * active OS interface.
+ *
+ * Returns:
+ * 0 - on success
+ * -1 - on error
+ */
+static int xc_osdep_get_info(xc_interface *xch, xc_osdep_info_t *info)
+{
+ int rc = -1;
+
+ *info = xc_osdep_info;
+
+ rc = 0;
+
+ return rc;
+}
+
+static void xc_osdep_put(xc_osdep_info_t *info)
+{
+}
+
static struct xc_interface_core *xc_interface_open_common(xentoollog_logger *logger,
- xentoollog_logger *dombuild_logger,
- unsigned open_flags,
- enum xc_interface_type type,
- int (*open_core)(struct xc_interface_core *xch))
+ xentoollog_logger *dombuild_logger,
+ unsigned open_flags,
+ enum xc_osdep_type type)
{
struct xc_interface_core xch_buf, *xch = &xch_buf;
xch->error_handler = logger; xch->error_handler_tofree = 0;
xch->dombuild_logger = dombuild_logger; xch->dombuild_logger_tofree = 0;
+ xch->ops_handle = XC_OSDEP_OPEN_ERROR;
+ xch->ops = NULL;
+
if (!xch->error_handler) {
xch->error_handler = xch->error_handler_tofree =
(xentoollog_logger*)
*xch = xch_buf;
if (!(open_flags & XC_OPENFLAG_DUMMY)) {
- xch->fd = open_core(xch);
- if (xch->fd < 0)
+ if ( xc_osdep_get_info(xch, &xch->osdep) < 0 )
goto err;
+
+ xch->ops = xch->osdep.init(xch, type);
+ if ( xch->ops == NULL )
+ goto err_put_iface;
+
+ xch->ops_handle = xch->ops->open(xch);
+ if (xch->ops_handle == XC_OSDEP_OPEN_ERROR)
+ goto err_put_iface;
}
return xch;
+err_put_iface:
+ xc_osdep_put(&xch->osdep);
err:
if (xch) xtl_logger_destroy(xch->error_handler_tofree);
if (xch != &xch_buf) free(xch);
- return 0;
+ return NULL;
}
-static int xc_interface_close_common(xc_interface *xch, int (*close_core)(struct xc_interface_core *xch))
+static int xc_interface_close_common(xc_interface *xch)
{
int rc = 0;
xtl_logger_destroy(xch->dombuild_logger_tofree);
xtl_logger_destroy(xch->error_handler_tofree);
- if (xch->fd >= 0) {
- rc = close_core(xch);
- if (rc) PERROR("Could not close hypervisor interface");
- }
+ rc = xch->ops->close(xch, xch->ops_handle);
+ if (rc) PERROR("Could not close hypervisor interface");
free(xch);
return rc;
xentoollog_logger *dombuild_logger,
unsigned open_flags)
{
- return xc_interface_open_common(logger, dombuild_logger, open_flags,
- XC_INTERFACE_PRIVCMD, &xc_interface_open_core);
+ xc_interface *xch;
+
+ xch = xc_interface_open_common(logger, dombuild_logger, open_flags,
+ XC_OSDEP_PRIVCMD);
+
+ return xch;
}
int xc_interface_close(xc_interface *xch)
{
- return xc_interface_close_common(xch, &xc_interface_close_core);
+ return xc_interface_close_common(xch);
}
xc_evtchn *xc_evtchn_open(xentoollog_logger *logger,
unsigned open_flags)
{
- return xc_interface_open_common(logger, NULL, open_flags,
- XC_INTERFACE_EVTCHN, &xc_evtchn_open_core);
+ xc_evtchn *xce;
+
+ xce = xc_interface_open_common(logger, NULL, open_flags,
+ XC_OSDEP_EVTCHN);
+
+ return xce;
}
int xc_evtchn_close(xc_evtchn *xce)
{
- return xc_interface_close_common(xce, &xc_evtchn_close_core);
+ return xc_interface_close_common(xce);
}
xc_gnttab *xc_gnttab_open(xentoollog_logger *logger,
unsigned open_flags)
{
return xc_interface_open_common(logger, NULL, open_flags,
- XC_INTERFACE_GNTTAB, &xc_gnttab_open_core);
+ XC_OSDEP_GNTTAB);
}
int xc_gnttab_close(xc_gnttab *xcg)
{
- return xc_interface_close_common(xcg, &xc_gnttab_close_core);
+ return xc_interface_close_common(xcg);
}
static pthread_key_t errbuf_pkey;
#include <sys/ioctl.h>
#include "xenctrl.h"
+#include "xenctrlosdep.h"
#include <xen/sys/privcmd.h>
*/
#define MAX_PAGECACHE_USAGE (4*1024)
-enum xc_interface_type {
- XC_INTERFACE_PRIVCMD,
- XC_INTERFACE_EVTCHN,
- XC_INTERFACE_GNTTAB,
-};
-
struct xc_interface_core {
- enum xc_interface_type type;
+ enum xc_osdep_type type;
int fd;
int flags;
xentoollog_logger *error_handler, *error_handler_tofree;
struct xc_error last_error; /* for xc_get_last_error */
FILE *dombuild_logger_file;
const char *currently_progress_reporting;
+
+ xc_osdep_info_t osdep;
+ xc_osdep_ops *ops; /* backend operations */
+ xc_osdep_handle ops_handle; /* opaque data for xc_osdep_ops */
};
void xc_report_error(xc_interface *xch, int code, const char *fmt, ...);
int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len);
-int xc_interface_open_core(struct xc_interface_core *xch); /* returns fd, logs errors */
-int xc_interface_close_core(struct xc_interface_core *xch); /* no logging */
-
-int xc_evtchn_open_core(struct xc_interface_core *xce); /* returns fd, logs errors */
-int xc_evtchn_close_core(struct xc_interface_core *xce); /* no logging */
-
-int xc_gnttab_open_core(struct xc_interface_core *xcg); /* returns fd, logs errors */
-int xc_gnttab_close_core(struct xc_interface_core *xcg); /* no logging */
-
void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
size_t size, int prot, size_t chunksize,
privcmd_mmap_entry_t entries[], int nentries);
#include <unistd.h>
#include <fcntl.h>
-int xc_interface_open_core(xc_interface *xch)
+static xc_osdep_handle solaris_privcmd_open(xc_interface *xch)
{
int flags, saved_errno;
int fd = open("/dev/xen/privcmd", O_RDWR);
if ( fd == -1 )
{
PERROR("Could not obtain handle on privileged command interface");
- return -1;
+ return XC_OSDEP_OPEN_ERROR;
}
/* Although we return the file handle as the 'xc handle' the API
goto error;
}
- return fd;
+ xch->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
error:
saved_errno = errno;
close(fd);
errno = saved_errno;
- return -1;
+ return XC_OSDEP_OPEN_ERROR;
}
-int xc_interface_close(xc_interface *xch, int fd)
+static int solaris_privcmd_close(xc_interface *xch, xc_osdep_handle h)
{
+ int fd = (int)h;
return close(fd);
}
return NULL;
}
-
static int do_privcmd(xc_interface *xch, unsigned int cmd, unsigned long data)
{
return ioctl(xch->fd, cmd, data);
(unsigned long)hypercall);
}
-int xc_evtchn_open_core(xc_evtchn *xce)
+static struct xc_osdep_ops solaris_privcmd_ops = {
+ .open = &solaris_privcmd_open,
+ .close = &solaris_privcmd_close,
+};
+
+static xc_osdep_handle solaris_evtchn_open(xc_evtchn *xce)
{
int fd;
if ( (fd = open("/dev/xen/evtchn", O_RDWR)) == -1 )
{
PERROR("Could not open event channel interface");
- return -1;
+ return XC_OSDEP_OPEN_ERROR;
}
- return fd;
+ xce->fd = fd; /* Remove after transition to full xc_osdep_ops. */
+ return (xc_osdep_handle)fd;
}
-int xc_evtchn_close_core(xc_evtchn *xce)
+static int solaris_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
{
- return close(xce->fd);
+ int fd = (int)h;
+ return close(fd);
}
int xc_evtchn_fd(xc_evtchn *xce)
return write_exact(xce->fd, (char *)&port, sizeof(port));
}
+static struct xc_osdep_ops solaris_evtchn_ops = {
+ .open = &solaris_evtchn_open,
+ .close = &solaris_evtchn_close,
+};
+
/* Optionally flush file to disk and discard page cache */
void discard_file_cache(xc_interface *xch, int fd, int flush)
{
// TODO: Implement for Solaris!
}
+
+static struct xc_osdep_ops *solaris_osdep_init(xc_interface *xch, enum xc_osdep_type type)
+{
+ switch ( type )
+ {
+ case XC_OSDEP_PRIVCMD:
+ return &solaris_privcmd_ops;
+ case XC_OSDEP_EVTCHN:
+ return &solaris_evtchn_ops;
+ case XC_OSDEP_GNTTAB:
+ ERROR("GNTTAB interface not supported on this platform");
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+xc_osdep_info_t xc_osdep_info = {
+ .name = "Solaris Native OS interface",
+ .init = &solaris_osdep_init,
+};
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/******************************************************************************
+ *
+ * Interface to OS specific low-level operations
+ *
+ * Copyright (c) 2010, Citrix Systems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This interface defines the interactions between the Xen control
+ * libraries and the OS facilities used to communicate with the
+ * hypervisor.
+ */
+
+#ifndef XC_OSDEP_H
+#define XC_OSDEP_H
+
+/* Tell the Xen public headers we are a user-space tools build. */
+#ifndef __XEN_TOOLS__
+#define __XEN_TOOLS__ 1
+#endif
+
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include <xen/sys/privcmd.h>
+
+enum xc_osdep_type {
+ XC_OSDEP_PRIVCMD,
+ XC_OSDEP_EVTCHN,
+ XC_OSDEP_GNTTAB,
+};
+
+/* Opaque handle internal to the backend */
+typedef unsigned long xc_osdep_handle;
+
+#define XC_OSDEP_OPEN_ERROR ((xc_osdep_handle)-1)
+
+struct xc_osdep_ops
+{
+ /* Opens an interface.
+ *
+ * Must return an opaque handle on success or
+ * XC_OSDEP_OPEN_ERROR on failure
+ */
+ xc_osdep_handle (*open)(xc_interface *xch);
+
+ int (*close)(xc_interface *xch, xc_osdep_handle h);
+};
+typedef struct xc_osdep_ops xc_osdep_ops;
+
+typedef xc_osdep_ops *(*xc_osdep_init_fn)(xc_interface *xch, enum xc_osdep_type);
+
+struct xc_osdep_info
+{
+ /* Describes this backend. */
+ const char *name;
+
+ /* Returns ops function. */
+ xc_osdep_init_fn init;
+};
+typedef struct xc_osdep_info xc_osdep_info_t;
+
+/* All backends, including the builtin backend, must supply this structure. */
+extern xc_osdep_info_t xc_osdep_info;
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */